function calc(code, array1, array2, b) {
  var count = 0;
  for (var i = 0; i < array2.length; i++) {
    var a = code[i];
    count += array2[i] * array1.indexOf(a);
  }
  var remainder = count % b;
  return remainder === 0 ? 0 : b - remainder;
}

// 身份证
export function validateSocialId(value) {
  if (value == "") {
    return false;
  } else {
    var firstarray = [
      "0",
      "1",
      "2",
      "3",
      "4",
      "5",
      "6",
      "7",
      "8",
      "9",
      "A",
      "B",
      "C",
      "D",
      "E",
      "F",
      "G",
      "H",
      "I",
      "J",
      "K",
      "L",
      "M",
      "N",
      "O",
      "P",
      "Q",
      "R",
      "S",
      "T",
      "U",
      "V",
      "W",
      "X",
      "Y",
      "Z",
    ];
    var firstkeys = [3, 7, 9, 10, 5, 8, 4, 2];
    var secondarray = [
      "0",
      "1",
      "2",
      "3",
      "4",
      "5",
      "6",
      "7",
      "8",
      "9",
      "A",
      "B",
      "C",
      "D",
      "E",
      "F",
      "G",
      "H",
      "J",
      "K",
      "L",
      "M",
      "N",
      "P",
      "Q",
      "R",
      "T",
      "U",
      "W",
      "X",
      "Y",
    ];
    var secondkeys = [
      1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28,
    ];

    var code = value.toUpperCase();
    if (code.length != 18) {
      return false;
    }
    var reg = /^\w\w\d{6}\w{9}\w$/;
    if (!reg.test(code)) {
      return false;
    } else {
      let reg1 = /^[1,5,9,Y]\w\d{6}\w{9}\w$/;
      if (!reg1.test(code)) {
        return false;
      } else {
        let reg2 =
          /^(11|12|13|19|21|31|32|33|34|35|41|51|52|53|54|55|61|62|59|71|72|81|91|92|93|A1|G1|J1|N1|N2|N3|Y1)\d{6}\w{9}\w$/;
        if (!reg2.test(code)) {
          return false;
        } else {
          let reg3 =
            /^(11|12|13|19|21|31|32|33|34|35|41|51|52|53|54|55|61|62|59|71|72|81|91|92|93|A1|G1|J1|N1|N2|N3|Y1)\d{6}\w{9}\w$/;
          if (!reg3.test(code)) {
            return false;
          } else {
            var firstkey = calc(code.substr(8), firstarray, firstkeys, 11);
            var firstword;
            if (firstkey < 10) {
              firstword = firstkey;
            }
            if (firstkey == 10) {
              firstword = "X";
            } else if (firstkey == 11) {
              firstword = "0";
            }
            if (firstword != code.substr(16, 1)) {
              return false;
            } else {
              var secondkey = calc(code, secondarray, secondkeys, 31);
              var secondword = secondarray[secondkey];
              if (!secondword || secondword != code.substr(17, 1)) {
                return false;
              } else {
                var word = code.substr(0, 16) + firstword + secondword;
                if (code != word) {
                  return false;
                } else {
                  return true;
                }
              }
            }
          }
        }
      }
    }
  }
}

// 校验身份证号
export function validateIdCard(certNo) {
  let birthday = null;
  let sex = null;
  let age = -1;

  if (certNo.length != 15 && certNo.length != 18) return false;

  // 15位的全部或18位的前17位必须位数字
  let str = certNo.length === 15 ? certNo : certNo.substring(0, 17);
  let regNum = /^\d+$/;
  if (!regNum.test(str)) return false;
  // 18位的最后一位可以是X或x
  let regLast = /[0-9Xx]/;
  let numLast = certNo.substring(17, 18);
  if (certNo.length === 18 && !regLast.test(numLast)) return false;

  // 前两位对应的区位码
  let zoneArr = [
    11, 12, 13, 14, 15, 21, 22, 23, 31, 32, 33, 34, 35, 36, 37, 41, 42, 43, 44,
    45, 46, 50, 51, 52, 53, 54, 61, 62, 63, 64, 65, 71, 81, 82, 91,
  ];
  if (zoneArr.indexOf(parseInt(certNo.substring(0, 2))) == -1) return false;

  // 校验年份、月份、日子
  let year =
    certNo.length === 15
      ? `19${certNo.substring(6, 8)}`
      : certNo.substring(6, 10);
  let month =
    certNo.length === 15 ? certNo.substring(8, 10) : certNo.substring(10, 12);
  let day =
    certNo.length === 15 ? certNo.substring(10, 12) : certNo.substring(12, 14);
  let dayNum = parseInt(day);
  let monthNum = parseInt(month);
  let yearNum = parseInt(year);

  let currentYear = new Date().getFullYear();
  if (yearNum < 1900 || yearNum > currentYear) return false;
  if (monthNum > 12 || monthNum < 1) return false;

  if (
    (monthNum === 1 ||
      monthNum === 3 ||
      monthNum === 5 ||
      monthNum === 7 ||
      monthNum === 8 ||
      monthNum === 10 ||
      monthNum === 12) &&
    dayNum > 31
  )
    return false;

  if (
    (monthNum === 4 || monthNum === 6 || monthNum === 9 || monthNum === 11) &&
    dayNum > 30
  )
    return false;

  // 校验闰平年二月的天数
  if (monthNum === 2) {
    let leapYear = null;
    // 闰年
    if ((yearNum % 4 === 0 && yearNum % 100 != 0) || yearNum % 400 === 0)
      leapYear = dayNum > 29 ? false : true;
    else {
      // 平年
      leapYear = dayNum > 28 ? false : true;
    }
    if (!leapYear) {
      return false;
    }
  }

  birthday = `${year}-${month}-${day}`;
  age = currentYear - year;
  if (certNo.length === 18) {
    sex = certNo.substring(16, 17) % 2 === 0 ? "女" : "男";
  } else {
    sex = certNo.substring(13, 14) % 2 === 0 ? "女" : "男";
  }

  // 校验 校验码
  const powerList = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
  const paritybitList = ["1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"];
  let num = 0;
  let certArr = certNo.split("").map(Number).slice(0, 17);

  for (let i = 0; i < certArr.length; i++) {
    num += certArr[i] * powerList[i];
  }

  if (certNo[17] != paritybitList[num % 11]) {
    if (num % 11 === 2) {
      if (certNo[17] != "x" && certNo[17] != "X") return false;
    } else {
      return false;
    }
  }

  return {
    birthday,
    sex,
    age,
  };
}

/**
 * Luhn校验算法校验银行卡号；Luhm校验规则：16位银行卡号（19位通用）:1、将未带校验位的 15（或18）位卡号从右依次编号 1 到 15（18），位于奇数位号上的数字乘以 2；2、将奇位乘积的个十位全部相加，再加上所有偶数位上的数字。
 * @param {string} bankno 银行卡号
 * @returns 是否为正确的银行卡号
 */
export function verifyBankCardNumber(bankno) {
  bankno = String(bankno);
  var lastNum = bankno.substring(bankno.length - 1); //取出最后一位（与luhm进行比较）
  var first15Num = bankno.substring(0, bankno.length - 1); //前15或18位
  var newArr = new Array();
  for (var i = first15Num.length - 1; i > -1; i--) {
    //前15或18位倒序存进数组
    newArr.push(first15Num.substring(i, i + 1));
  }
  var arrJiShu = new Array(); //奇数位*2的积 <9
  var arrJiShu2 = new Array(); //奇数位*2的积 >9
  var arrOuShu = new Array(); //偶数位数组
  for (var j = 0; j < newArr.length; j++) {
    if ((j + 1) % 2 == 1) {
      //奇数位
      if (parseInt(newArr[j]) * 2 < 9) arrJiShu.push(parseInt(newArr[j]) * 2);
      else arrJiShu2.push(parseInt(newArr[j]) * 2);
    } //偶数位
    else arrOuShu.push(newArr[j]);
  }
  var jishu_child1 = new Array(); //奇数位*2 >9 的分割之后的数组个位数
  var jishu_child2 = new Array(); //奇数位*2 >9 的分割之后的数组十位数
  for (var h = 0; h < arrJiShu2.length; h++) {
    jishu_child1.push(parseInt(arrJiShu2[h]) % 10);
    jishu_child2.push(parseInt(arrJiShu2[h]) / 10);
  }
  var sumJiShu = 0; //奇数位*2 < 9 的数组之和
  var sumOuShu = 0; //偶数位数组之和
  var sumJiShuChild1 = 0; //奇数位*2 >9 的分割之后的数组个位数之和
  var sumJiShuChild2 = 0; //奇数位*2 >9 的分割之后的数组十位数之和
  var sumTotal = 0;
  for (var m = 0; m < arrJiShu.length; m++) {
    sumJiShu = sumJiShu + parseInt(arrJiShu[m]);
  }
  for (var n = 0; n < arrOuShu.length; n++) {
    sumOuShu = sumOuShu + parseInt(arrOuShu[n]);
  }
  for (var p = 0; p < jishu_child1.length; p++) {
    sumJiShuChild1 = sumJiShuChild1 + parseInt(jishu_child1[p]);
    sumJiShuChild2 = sumJiShuChild2 + parseInt(jishu_child2[p]);
  }
  //计算总和
  sumTotal =
    parseInt(sumJiShu) +
    parseInt(sumOuShu) +
    parseInt(sumJiShuChild1) +
    parseInt(sumJiShuChild2);
  //计算Luhm值
  var k = parseInt(sumTotal) % 10 == 0 ? 10 : parseInt(sumTotal) % 10;
  var luhm = 10 - k;
  var result = false;
  if (lastNum == luhm) {
    //Luhm验证通过
    result = true;
  } else {
    //银行卡号必须符合Luhm校验
    result = false;
  }
  return result;
}
